﻿using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Test.Account.Manager;
using Test.DataAccess.POCO;
using Test.IOC;
using Test.Site.Data.Helper;
using Test.Utility.Extensions;
using Test.Web.Infrastructure.Constant;
using Test.Web.Models.Sessions;

namespace Test.Web.Infrastructure
{

    public class AdminAuthorizeAttribute : AuthorizeAttribute
    {
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            FormsAuthenticationHelper.RenewCurrentUser();
            if (!base.AuthorizeCore(httpContext))
            {
                return false;
            }
            else
            {
                var adminSession = HttpContext.Current.Session[SessionConstant.ADMIN_SESSION] as AdminSession;

                //如果cookie还有效，但是session已经失效，重新初始化session
                if (adminSession.IsNull())
                {
                    var adminManager = Factory.StaticGetObject<AdminManager>();
                    var permissionManager = Factory.StaticGetObject<PermissionManager>();

                    var adminId = httpContext.User?.Identity?.Name;
                    var admin = adminManager.Get(a => a.Id == adminId);

                    if (admin == null)//cookie有效，但是登录的可能是前台系统
                    {
                        return false;
                    }
                    IEnumerable<Permission> allPermission = null;
                    if (admin.IsSuperAdmin)
                    {
                        allPermission = permissionManager.All();
                    }
                    else
                    {
                        allPermission = admin.Roles.SelectMany(r => r.Permissions);
                    }

                    adminSession = new AdminSession(admin, allPermission);
                    HttpContext.Current.Session[SessionConstant.ADMIN_SESSION] = adminSession;
                }

                if (adminSession.IsNotNull() && adminSession.IsSuperAdmin)
                {
                    return true;
                }
                else if (adminSession.IsNotNull())
                {
                    //所有的权限列表
                    var allPermissions = Factory.StaticGetObject<PermissionManager>().GetAllPermissionCache();

                    //当前请求的controller和action
                    var controller = httpContext.Request.RequestContext.RouteData.Values["controller"].AsString();
                    var action = httpContext.Request.RequestContext.RouteData.Values["action"].AsString();
                    var url = httpContext.Request.Url?.AbsolutePath;

                    //在所有权限里查找最精确的权限
                    var permission = allPermissions.FirstOrDefault(p => p.Url == url);
                    if (permission.IsNull())
                    {
                        permission = allPermissions.FirstOrDefault(p => p.Controller.EqualsNoCase(controller) && p.Action.EqualsNoCase(action));
                    }
                    //如果没有完全相等的权限，找controller权限             
                    if (permission.IsNull())
                    {
                        permission = allPermissions.FirstOrDefault(p => p.Controller.EqualsNoCase(controller) && (p.Action == null || p.Action == ""));
                    }

                    if (permission.IsNotNull())
                    {
                        var b = adminSession.AllPermissions.Count(p => permission.Id == p.Id) > 0;
                    }
                    //如果还没有，说明该链接不需要特殊权限，直接允许；如果有，就判断用户是否有此权限
                    return permission.IsNull() || adminSession.AllPermissions.Count(p => permission.Id == p.Id) > 0;
                }
                else
                {
                    return false;
                }
            }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.Result = new JsonResult()
                {
                    Data = new { }//ajax授权失败
                };
            }
            else
            {
                filterContext.Result = new RedirectToRouteResult(RouteConfig.AdminDefault,
                    RouteValuesHelper.From(
                        new
                        {
                            controller = "Account",
                            action = "Login",
                            returnUrl = filterContext.RequestContext.HttpContext.Request.RawUrl
                        })
                );
            }
        }
    }
}